// import update from 'immutability-helper'
import type { FC } from 'react'
import { useCallback, useEffect, useRef, useState } from 'react'

import { Card, DragItem, IStateRefProps } from '../card'
import { DropTargetMonitor, useDrop } from 'react-dnd'
import { Anchor } from '../anchor'
import { setState, useStateFromRedux } from '../../reducer'
import { produce } from 'immer'
import React from 'react'
import { compareIndexs, findCardByIndexs } from '../../helper'
import Contexify from '../contexify'
import { ItemParams } from 'react-contexify'
import styles from './index.module.less'

export interface Item {
  id: number
  text: string
}

export interface ContainerState {
  cards: Item[]
}



export type currentDropBoxesProps = {
  dropBoxes: Map<string, number>
  currentDropBox: string
}

export interface ChangePosLineProps {
  top?: number
  left?: number
  width?: number
  height?: number
  index?: number
  show: boolean
  direction?: string
}

export type HoverDragItem = Omit<DragItem, 'width' | 'height'> & { width: number, height: number }

// 靠近吸附阈值
const THRESHOLD = 10;

// 拖拽元素top和left定位数据
let pos = {
  top: 0,
  left: 0,
}
const setPos = (data: { left: number, top: number }) => (pos = {
  left: data.left,
  top: data.top
})

export const Container: FC<{ componentLibs: Map<string, React.ComponentType<unknown>>, style: React.CSSProperties }> = ({ componentLibs, style }) => {
  const ref = useRef<HTMLDivElement | null>(null);
  const canDrop = useRef(false);
  const setCanDrop = (bool: boolean) => canDrop.current = bool;
  const [showDimension, setShowDimension] = useState(false);
  const currentDropBoxes = useRef<currentDropBoxesProps>({
    dropBoxes: new Map(),
    currentDropBox: '',
  })
  const [selectIndex, setSelectIndex] = useStateFromRedux('selectIndex')
  const [cards, setCards] = useStateFromRedux('cards')
  // console.log('cards', cards)

  const [containerRect, setContainerRect] = useState({ top: 0, left: 0 });
  const [hoverIndex, setHoverIndex] = useState(-1);
  const [line, setLine] = useState<ChangePosLineProps>({
    top: 0,
    left: 0,
    width: 0,
    height: 0,
    index: -1,
    show: false,
  })
  const [anchorState, setAnchorState] = useState({
    top: 0,
    left: 0,
    width: 0,
    height: 0,
  })
  // 辅助框
  const [referenceRect, setReferenceRect] = useState({
    left: 0,
    top: 0,
    width: 0,
    height: 0,
  })
  // 竖直中心辅助线
  const [reference, setReference] = useState({
    x: 0,
    y: 0
  })
  // 靠近吸附参考线
  const [referenceLines, setReferenceLines] = useState<{type: string, top?: number, left?: number}[]>([])

  /**
   * 更新锚点状态
   */
  const changeAnchorState = () => {
    console.log('changeAnchorState',)
    const ele = document.querySelector(`[data-id="${findCardByIndexs(cards, selectIndex)?.id}"]`);
    if (ele) {
      const rect = ele.getBoundingClientRect();
      // console.log('rect', rect,
      //   rect.top - containerRect.top
      // )
      setAnchorState({
        // top需要补偿滚动偏移
        top: rect.top - containerRect.top + (((document.querySelector('#dragger')?.scrollTop || 0) + (document.querySelector('#dragger-wrapper')?.scrollTop || 0)) || 0),
        left: rect.left - containerRect.left,
        width: rect.width,
        height: rect.height,

      })

    }
  }

  /**
   * 获取拖拽元素的left top值，并自动吸附边界
   */
  const getPosData = (monitor: DropTargetMonitor<unknown, unknown>, dragItem: HoverDragItem) => {
      let left = monitor.getSourceClientOffset()!.x - containerRect.left;
      let top = monitor.getSourceClientOffset()!.y - containerRect.top + (document.querySelector('#dragger')?.scrollTop || 0 + (document.querySelector('#dragger-wrapper')?.scrollTop || 0) || 0)
      
      const centerY = 375 / 2;

      // 自动吸附Y中心线  
      const rx = left + (dragItem.width / 2);
      left = Math.abs(centerY - rx) < 10 ? centerY - (dragItem.width / 2) : left;

      // 自动吸附左边界
      if (Math.abs(left) < 10) left = 0;

      // 自动吸附右边界
      if (Math.abs((left + dragItem.width) - 375) < 10) left = 375 - dragItem.width;

      // 自动吸附上边界
      if (Math.abs(top) < 10) top = 0;

      setPos({
        left,
        top,
      })

      return pos;
  }

  /**
   * 计算获取上下左右附近靠近元素的吸附参考线
   */
  const getReferenceLines = (dragItem: HoverDragItem) => {
    const { left, top } = pos;
    const lines = [] as {type: string, top?: number, left?: number}[];
    const card = findCardByIndexs(cards, selectIndex);
    if (dragItem.type !== 'static' && (dragItem.type === 'anchor' && card.type !== 'static')) {
      cards.map((card: DragItem, i: number) => {
        if (dragItem.index === i) return;
        // top line
        if (Object.prototype.hasOwnProperty.call(card, 'top')) {
          if (Math.abs(top - card.top!) < THRESHOLD) {
            lines.push({
              type: 'row',
              top: card.top,
            })
          } else if (Math.abs(top - (Number(card.top) + Number(card.height))) < THRESHOLD) {
            lines.push({
              type: 'row',
              top: Number(card.top) + Number(card.height),
            })
          }
        }

        // bottom line
        if (Object.prototype.hasOwnProperty.call(card, 'top')) {
          if (Math.abs((top + dragItem.height) - card.top!) < THRESHOLD) {
            lines.push({
              type: 'row',
              top: card.top,
            })
          } else if (Math.abs((top + dragItem.height) - (Number(card.top) + Number(card.height))) < THRESHOLD) {
            lines.push({
              type: 'row',
              top: Number(card.top) + Number(card.height),
            })
          }
        }

        // left line
        if (Object.prototype.hasOwnProperty.call(card, 'left')) {
          if (Math.abs(left - Number(card.left)) < THRESHOLD) {
            lines.push({
              type: 'column',
              left: card.left,
            })
          } else if (Math.abs(left - (Number(card.left) +  Number(card.width))) < THRESHOLD) {
            lines.push({
              type: 'column',
              left: Number(card.left) +  Number(card.width),
            })
          }
        }

        // right line
        if (Object.prototype.hasOwnProperty.call(card, 'left')) {
          if (Math.abs((left + dragItem.width) - Number(card.left)) < THRESHOLD) {
            lines.push({
              type: 'column',
              left: card.left,
            })
          } else if (Math.abs((left + dragItem.width) - (Number(card.left) + Number(card.width))) < THRESHOLD) {
            lines.push({
              type: 'column',
              left: Number(card.left) + Number(card.width),
            })
          }
        }
      })
    }

    setReferenceLines(lines as never[]);
  }

  /**
   * 获取所有锚点位置信息，并更新元素位置尺寸
   */
  const getAnchorData = (monitor: DropTargetMonitor<unknown, unknown>, dragItem: HoverDragItem) => {
    if (dragItem.type === 'anchor') {
      const {left, top} = pos; 
      const sourceClient = monitor.getSourceClientOffset();
      const initSourceClient = monitor.getInitialSourceClientOffset();
      const offsetX = (sourceClient?.x || 0) - (initSourceClient?.x || 0);
      const offsetY = (sourceClient?.y || 0) - (initSourceClient?.y || 0);

      let l: number = 0, t: number = 0, w: number = 0, h: number = 0;
      switch (dragItem.direction) {
        case 'leftTop':
          l = left;
          t = top;
          w = dragItem.width - offsetX;
          h = dragItem.height - offsetY;
          break;
        case 'rightTop':
          l = dragItem.left!;
          t = dragItem.top! + offsetY;
          w = dragItem.width + offsetX;
          h = dragItem.height - offsetY;
          break;
        case 'leftBottom':
          l = dragItem.left! + offsetX;
          t = dragItem.top!;
          w = dragItem.width - offsetX;
          h = dragItem.height + offsetY;
          break;
        case 'rightBottom':
          l = dragItem.left!;
          t = dragItem.top!;
          w = dragItem.width + offsetX;
          h = dragItem.height + offsetY;
          break;
        case 'upCenter':
          l = dragItem.left!;
          t = dragItem.top! + offsetY;
          w = dragItem.width;
          h = dragItem.height - offsetY;
          break;
        case 'downCenter':
          l = dragItem.left!;
          t = dragItem.top!;
          w = dragItem.width;
          h = dragItem.height + offsetY;
          break;
        case 'leftCenter':
          l = dragItem.left! + offsetX;
          t = dragItem.top!;
          w = dragItem.width - offsetX;
          h = dragItem.height;
          break;
        case 'rightCenter':
          l = dragItem.left!;
          t = dragItem.top!;
          w = dragItem.width + offsetX;
          h = dragItem.height;
          break;
      }
      // 设置最小宽高为1
      if (w <= 0) w = 1;
      if (h <= 0) h = 1;
      setAnchorState({
        left: l,
        top: t,
        width: w,
        height: h
      })
      setCards(produce((draft) => {
        const card = findCardByIndexs(draft, selectIndex);
        card.left = l;
        card.top = t;
        card.width = w;
        card.height = h;
      }))
      !showDimension && setShowDimension(true);
    }
  }

  const [{ isOver }, drop] = useDrop({
    accept: ['static', 'fixed', 'anchor'],
    collect(monitor) {
      return {
        handlerId: monitor.getHandlerId(),
        didDrop: monitor.didDrop(),
        isOver: monitor.isOver(),
      }
    },
    drop(item) {
      const dragItem = item as DragItem;
      // 隐藏尺寸提示
      setShowDimension(false)
      // 隐藏辅助框
      setReferenceRect({
        top: 0,
        left: 0,
        width: 0,
        height: 0,
      })
      // 隐藏中心辅助线
      setReference({
        x: 0,
        y: 0,
      })
      // 隐藏参考线
      setReferenceLines([]);
      // 锚点不用落
      if (dragItem.type === 'anchor') return;

      if (!canDrop.current) return
      console.log('Container', dragItem, canDrop.current, dragItem.type === 'fixed' && dragItem.id)

      // 悬浮组件移动位置
      if (dragItem.type === 'fixed' && dragItem.id) {
        setCards(produce((draft: DragItem[]) => {
          draft[dragItem.index].left = pos.left;
          draft[dragItem.index].top = pos.top;
        }))
        setSelectIndex(dragItem.indexs)
        return
        // 静态组件交换位置
      } else if (dragItem.type === 'static' && dragItem.id) {
        moveCard(dragItem.indexs, [cards.length - 1], { isUp: false })
        setSelectIndex([cards.length - 1])
        setLine({ show: false })
        // 其他都是拖拽新增组件
      } else {
        console.log('【container】addCard', dragItem, {}, [cards.length + 1])
        addCard(dragItem, {}, { addIndex: [cards.length], isUp: false, isLeft: false })
        // 选中新增项
        // 延迟100ms,等图片加载完成再选中组件
        setTimeout(() => {
          setSelectIndex([cards.length])
        }, 100)

      }
    },
    hover(item, monitor) {
      const dragItem = item as HoverDragItem;
      setCanDrop(true)
      // console.log(
      //   'Container',
      //   // item,
      //   monitor.getClientOffset(),
      //   monitor.getSourceClientOffset(),
      //   monitor.getInitialSourceClientOffset(),
      //   monitor.getInitialClientOffset()
      // )
      // const hoverBoundingRect = ref.current!.getBoundingClientRect()
      // 获取拖拽元素定位left和top值
      const { left, top } = getPosData(monitor, dragItem);

      // 1. 拖拽锚点不显示矩形参考线
      // 2. 新增不显示矩形参考线，dragItem.id为空是新增组件
      if (dragItem.type !== 'anchor' && dragItem.id) {
        setReferenceRect({
          top: top,
          left,
          width: dragItem.width,
          height: dragItem.height
        })
      }

      // 获取所有靠近元素时显示的吸附参考线
      getReferenceLines(dragItem);
      
      // 显示页面中心竖直参考线
      setReference({
        x: left + (dragItem.width / 2),
        y: top + (dragItem.height / 2),
      })

      // 锚点位置更新，元素位置更新
      getAnchorData(monitor, dragItem);
    }
  })

  

  const moveCard = (dragIndexs: number[], dropIndexs: number[], position: IStateRefProps) => {
    if (dragIndexs.toString() === dropIndexs.toString()) return;
    console.log('【moveCard】：拖拽元素', dragIndexs,'至', dropIndexs, ',方向:', position, cards)
    const { isUp } = position;
    const indexsInfo = compareIndexs(dragIndexs, dropIndexs)
    let dropIsFlexBox = false;
    let newDragIndex = 0;
    setCards(produce((draft: DragItem[]) => {
      let parentDropCard, parentDragCard, dropCard, dragCard, dropList, dragList, dropDirection;
      if (indexsInfo.parentDropIsRoot) {
        parentDropCard = draft
        dropCard = parentDropCard[indexsInfo.dropIndex];
        dropList = parentDropCard;
        dropDirection = 'column'
      } else {
        parentDropCard = findCardByIndexs(draft, indexsInfo.parentDropIndexs)
        dropCard = parentDropCard.childrens[indexsInfo.dropIndex];
        dropList = parentDropCard.childrens;
        dropDirection = parentDropCard.direction;
      }

      if (indexsInfo.parentDragIsRoot) {
        parentDragCard = draft
        dragCard = parentDragCard[indexsInfo.dragIndex];
        dragList = parentDragCard;
      } else { 
        parentDragCard = findCardByIndexs(draft, indexsInfo.parentDragIndexs)
        dragCard = parentDragCard.childrens[indexsInfo.dragIndex];
        dragList = parentDragCard.childrens;
      }
      // drag元素direction需要和drop元素方向一致
      dragCard = { ...dragCard, direction: dropDirection }

      // 如果drop是容器,则移动到容器末尾位置，而不是和容器交换位置
      if(dropCard.mode === 'box') {
        dropIsFlexBox = true;
        dragList.splice(indexsInfo.dragIndex, 1);
        dropCard.childrens.splice(dropCard.childrens.length, 0, dragCard);
        newDragIndex = dropCard.childrens.length - 1;
      // drop未非弹性容器，则交换位置
      // 同一个列表前后移动需要判断增删先后顺序
      } else if (indexsInfo.isSameParent && dragCard) {
        // 往前移动，先删后增
        if (indexsInfo.dragDirection === 'before') {
          dragList.splice(indexsInfo.dragIndex, 1);
          dropList.splice(isUp ? indexsInfo.dropIndex : indexsInfo.dropIndex + 1, 0, dragCard)
          // 往后移动，先增后删
        } else {
          dropList.splice(isUp ? indexsInfo.dropIndex : indexsInfo.dropIndex + 1, 0, dragCard)
          dragList.splice(indexsInfo.dragIndex, 1);
        }
        // 不在同一个列表不用判断
      } else {
        dropList.splice(isUp ? indexsInfo.dropIndex : indexsInfo.dropIndex + 1, 0, dragCard)
        dragList.splice(indexsInfo.dragIndex, 1);
      }
    }))

    // 移动后选中元素，依赖上面移动位置时插入弹性容器的位置信息
    if (dropIsFlexBox) {
      // 如果在移动元素和弹性容器为同一个列表，弹性容器若在后面，弹性容器坐标会前移一位
      if (indexsInfo.isSameParent && indexsInfo.dropIndex > indexsInfo.dragIndex) {
        dropIndexs[dropIndexs.length - 1] -= 1;
      }
      // drag插入到drop列表的末尾
      dropIndexs.push(newDragIndex);
    }
    setSelectIndex(dropIndexs)
  }

  const addCard = (dragItem: DragItem, dropItem: Partial<DragItem>, position: IStateRefProps) => {
    console.log('【addCard】：新增元素', dragItem,'至', dropItem, ',方向:', position, cards)
    const { addIndex, isUp } = position;
    let newDragIndex = 0
    setCards(produce((draft: DragItem[]) => {
      // 落在嵌套容器里面的组件上
      if (addIndex && addIndex.length > 1 && dropItem.name !== 'FlexBox' && dropItem.mode !== 'box') {
        let lastIndex = addIndex.pop() as number;
        if (!isUp) {
          lastIndex += 1;
        }
        let arr = draft;
        let direction;
        addIndex.map(index => {
          direction = arr[index].direction || 'column';
          arr = arr[index].childrens
        })
        arr.splice(lastIndex, 0, { ...dragItem, id: new Date().getTime(), ...(dragItem.type === 'fixed' ? pos : {}), direction })
        addIndex.push(lastIndex);
        // 落在嵌套容器里面且未落到容器里面的组件上
      } else if (dropItem.mode === 'box') {
        let arr = draft;
        let direction;
        addIndex!.map(index => {
          direction = arr[index].direction || 'column';
          arr = arr[index].childrens
        })
        arr.push({ ...dragItem, id: new Date().getTime(), ...(dragItem.type === 'fixed' ? pos : {}), direction })
        newDragIndex = arr.length - 1;
        // 落在页面上（非嵌套容器内）
      } else {
        draft.splice(addIndex![0], 0, { ...dragItem, id: new Date().getTime(), ...(dragItem.type === 'fixed' ? pos : {}) })
      }
    }))

    // 添加后选中元素，弹性容器往里面插入元素，其它则是上方或下方插入
    if (dropItem.mode === 'box') {
      // drag插入到drop列表的末尾
      (addIndex || []).push(newDragIndex);
    }
    setSelectIndex(addIndex)
  }

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const copyCard = (params: ItemParams<any, any>) => {
    console.log('【copyCard】：复制元素', params)
    const { props: { indexs, item }  } = params;
    const dragItem = item;
    const dropItem = item;
    const addIndex = [...indexs];
    // addIndex[addIndex.length - 1] += 1;
    const position = {
      isUp: false,
      addIndex
    }
    // debugger
    addCard(dragItem, dropItem, position);
  }

  const deleteCard = (params: ItemParams<any, any>) => {
    console.log('【deleteCard】：删除元素', params)
    const { props: { indexs }  } = params;
    const indexsInfo = compareIndexs(indexs, [])
    setCards(produce((draft: DragItem[]) => {
      let dragList, parentDragCard;
      if (indexsInfo.parentDragIsRoot) {
        parentDragCard = draft
        dragList = parentDragCard;
      } else { 
        parentDragCard = findCardByIndexs(draft, indexsInfo.parentDragIndexs)
        dragList = parentDragCard.childrens;
      }
      dragList.splice(indexsInfo.dragIndex, 1);
    }))
    setSelectIndex([])
  }

  const changeZIndex = (params: ItemParams<any, any>, addZIndex = 1) => {
    console.log('【changeZIndex】：修改元素层级', params, addZIndex)
    const { props: { indexs }  } = params;
    const indexsInfo = compareIndexs(indexs, [])
    setCards(produce((draft: DragItem[]) => {
      let dragCard, parentDragCard;
      if (indexsInfo.parentDragIsRoot) {
        parentDragCard = draft
        dragCard = parentDragCard[indexsInfo.dragIndex];
      } else { 
        parentDragCard = findCardByIndexs(draft, indexsInfo.parentDragIndexs)
        dragCard = parentDragCard.childrens[indexsInfo.dragIndex];
      }
      dragCard.zIndex += addZIndex; 
    }))
  }

  const selectParent = (params: ItemParams<any, any>) => {
    console.log('【selectParent】：选中父级元素', params)
    const { props: { indexs }  } = params;
    indexs.pop();
    setSelectIndex(indexs)
  }

  // eslint-disable-next-line react-hooks/exhaustive-deps
  const changeRect = useCallback((arrow: string, selectIndex: number[]) => {
    console.log('【changeRect】：微调元素', arrow, selectIndex)
    const indexsInfo = compareIndexs(selectIndex, [])
    setCards(produce((draft: DragItem[]) => {
      let dragCard, parentDragCard;
      if (indexsInfo.parentDragIsRoot) {
        parentDragCard = draft
        dragCard = parentDragCard[indexsInfo.dragIndex];
      } else { 
        parentDragCard = findCardByIndexs(draft, indexsInfo.parentDragIndexs)
        dragCard = parentDragCard.childrens[indexsInfo.dragIndex];
      }

      if (arrow === 'ArrowUp') {
        dragCard.height -= 1;
      } else if (arrow === 'ArrowDown') {
        dragCard.height += 1;
      } else if (arrow === 'ArrowLeft') {
        dragCard.width -= 1;
      } else if (arrow === 'ArrowRight') {
        dragCard.width += 1;
      }
      setTimeout(() => {
        changeAnchorState();
      }, 0)
    }))
  }, [setCards])

  const changeRectListener = useCallback((e) => {
    // console.log('keydown', e)
    if (e.ctrlKey && e.code === 'ArrowDown') {
      console.log('ArrowDown')
      changeRect('ArrowDown', selectIndex)
    } else if (e.ctrlKey && e.code === 'ArrowUp'){
      console.log('ArrowUp')
      changeRect('ArrowUp', selectIndex)
    } else if (e.ctrlKey && e.code === 'ArrowLeft'){
      console.log('ArrowLeft')
      changeRect('ArrowLeft', selectIndex)
    } else if (e.ctrlKey && e.code === 'ArrowRight'){
      console.log('ArrowRight')
      changeRect('ArrowRight', selectIndex)
    } else if (e.code === 'Delete' && selectIndex.length > 0) {
      deleteCard({
        props: { indexs: selectIndex, event: null },
      } as ItemParams<any, any>)
    }
  }, [selectIndex, changeRect])

  drop(ref)

  // 更新画布矩形位置信息，用来计算锚点位置信息
  const updateContainerRect = () => {
    setContainerRect(ref.current!.getBoundingClientRect())
  }

  useEffect(() => {
    updateContainerRect()
    window.addEventListener('resize', updateContainerRect)
    return () => window.removeEventListener('resize', updateContainerRect)
  }, [])

  useEffect(() => {
    console.log('【selectIndex change】', selectIndex)
    changeAnchorState();
  }, [selectIndex])

  useEffect(() => {
    console.log('【监听键盘按下事件】')
    // 通过ctrl+↑ 和 ctrl+↓来微调宽高
    document.addEventListener('keydown', changeRectListener)
    return () => document.removeEventListener('keydown', changeRectListener)
  }, [changeRectListener])

  const renderCard = (card: DragItem, index: number, indexs?: number[]) => {
    // console.log('renderCard', card)
    if (card.mode === 'box') {
      indexs = indexs || [index];
      return <Card
        containerRef={ref}
        // direction={card.direction || 'column'}
        data={card}
        key={card.id}
        index={index}
        indexs={indexs}
        hoverIndex={hoverIndex}
        setHoverIndex={(i) => { console.log('i', i); setHoverIndex(i) }}
        moveCard={moveCard}
        addCard={addCard}
        canDrop={canDrop}
        setCanDrop={setCanDrop}
        selectIndex={selectIndex}
        setSelectIndex={setSelectIndex}
        setLine={setLine}
        containerRect={containerRect}
        componentLibs={componentLibs}
        currentDropBoxes={currentDropBoxes}
      >
        {card.childrens.map((children, cIndex) => {
          const childrenIndexArr = [...(indexs || [])];
          childrenIndexArr.push(cIndex)
          return renderCard(children, cIndex, childrenIndexArr)
        })}
      </Card>
    }
    return (
      <Card
        // direction={card.direction || 'column'}
        containerRef={ref}
        data={card}
        key={card.id}
        index={index}
        indexs={indexs || [index]}
        hoverIndex={hoverIndex}
        setHoverIndex={(i) => { console.log('i', i); setHoverIndex(i) }}
        moveCard={moveCard}
        addCard={addCard}
        canDrop={canDrop}
        setCanDrop={setCanDrop}
        selectIndex={selectIndex}
        setSelectIndex={setSelectIndex}
        setLine={setLine}
        containerRect={containerRect}
        componentLibs={componentLibs}
        currentDropBoxes={currentDropBoxes}
      />
    )
  }

  console.log('isOver', isOver, cards)
  return (
    <div style={{...style}} className={styles.draggerWrapper} id="dragger-wrapper" ref={ref}>
      {/**页面组件列表 */}
      {cards.map((card: DragItem, i: number) => renderCard(card, i))}
      {/**拖拽锚点 */}
      {<Anchor {...anchorState} showDimension={showDimension} selectIndex={selectIndex} cards={cards} />}
      {/**交换位置参考线 */}
      {
      isOver && line.show && 
      <div style={{ 
        position: 'absolute', 
        zIndex: 150, 
        ...line, 
        top: line.direction === 'row' ? line.top! - 1 : line.top, 
        left: line.direction === 'column' ? line.left! - 1 : line.left, 
        background: '#722ed1' , 
        pointerEvents: 'none' } as React.CSSProperties}
      ></div>}
      {/**中心参考线 */}
      {!!reference.x && Math.abs(375 / 2 - reference.x) < 10 && <div style={{ height: '100%', width: 1, background: 'red', position: 'absolute', left: 375 / 2 + 'px', top: 0 }}></div>}

      {/**靠近吸附参考线 */}
      {
        referenceLines.map(line => {
          if (line.type === 'row') return <div style={{ height: 1, width: '100%', background: 'red', position: 'absolute', top: line.top + 'px' }}></div>
          if (line.type === 'column') return <div style={{ height: '100%', width: 1, background: 'red', position: 'absolute', left: line.left + 'px' }}></div>
        })
      }
      {/**矩形位置参考线，必须在容器内移动 */}
      {isOver && referenceRect.width > 0 && <div className={styles.referenceRect} style={{ ...referenceRect }}></div>}

      {/* 右键菜单 */}
      <Contexify copyCard={copyCard} deleteCard={deleteCard} changeZIndex={changeZIndex} selectParent={selectParent}/>
    </div>
  )

}

